/**
 * Copyright (c) 2020 qar All rights reserved.
 * <p>
 * https://www.qar.io
 * <p>
 * 版权所有，侵权必究！
 */
package com.example.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.example.dto.PasswordLoginDTO;
import com.example.exception.BaseException;
import com.example.model.api.Result;
import com.example.redis.RedisKeys;
import com.example.redis.RedisUtils;
import com.example.security.InfoDetail;
import com.example.service.CaptchaService;
import com.example.service.JwtBlacklistService;
import com.example.service.LoginService;
import com.example.utils.HttpContextUtils;
import com.example.validator.AssertUtils;
import com.example.validator.ValidatorUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;

/**
 * 验证码
 *
 * @author Mark sunlightcs@gmail.com
 */
@Tag(name = "用户名密码登录(待验证码)")
@RestController
@AllArgsConstructor
public class PasswordLoginController {
    private CaptchaService captchaService;
    private LoginService loginService;

//    private CaptchaService captchaService;
//    private LoginService loginService;
    @Autowired
    private JwtBlacklistService jwtBlacklistService;
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private JwtDecoder jwtDecoder;

    @GetMapping("captcha")
    @Operation(summary = "验证码")
    public void captcha(HttpServletResponse response,
                        @Parameter(name = "uuid", description = "验证码的UUID", required = true, example = "123")
                        @RequestParam("uuid") String uuid) throws IOException {
        //uuid不能为空
        AssertUtils.isBlank(uuid, "uuid不能为空");

        //生成验证码
        captchaService.create(response, uuid);
    }

    @PostMapping("/captcha/login")
    public Result<Map<String, Object>> login(@RequestBody PasswordLoginDTO loginDTO) {
        ValidatorUtils.validateEntity(loginDTO);
        return loginService.passwordLogin(loginDTO);
    }

    @PostMapping("/captcha/logout")
    public Result<String> logout(HttpServletRequest request) {
        // 在网关中，将请求头中的token(或者参数中的token)值提取出来,放入了Authorization
        String authorizationHeader = request.getHeader("Authorization");
        if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
            throw new BaseException("无效的token格式");
        }
        String tokenValue = authorizationHeader.substring(7); // 提取token值
        if (StrUtil.isEmpty(tokenValue)) {
            throw new BaseException("Token未提供");
        }
        try {
            // 使用Spring Security的JwtDecoder来解析token
            Jwt jwt = jwtDecoder.decode(tokenValue);

            // 获取token的过期时间等（这里以过期时间为例）
            Instant expiresAt = jwt.getExpiresAt();
            long timeout = Duration.between(Instant.now(), expiresAt).toMillis();

            // 获取token的声明（claims）
            Map<String, Object> claims = jwt.getClaims();
            if (!claims.containsKey("infoDetail")) {
                throw new BaseException("令牌信息不完整");
            }
            InfoDetail infoDetail;
            try {
                String json = JSON.toJSONString(claims.get("infoDetail"));
                infoDetail = JSON.parseObject(json, InfoDetail.class);
            } catch (Exception e) {
                throw new BaseException("用户信息解析失败");
            }

            // 加入黑名单（确保timeout非负）
            if (timeout > 0) {
                jwtBlacklistService.addToBlacklist(tokenValue, timeout);
            }

            // 清理Redis（使用具体键值） 1916321720709550080
            Long userId = infoDetail.getId();
            redisUtils.delete(RedisKeys.getUserMenuNavKey(userId));
            redisUtils.delete(RedisKeys.getUserPermissionsKey(userId));

            return new Result<String>().ok("ok");
        } catch (JwtException e) {
            // 处理JWT解析异常（如签名不匹配、token过期等）
            throw new BaseException("无效的token");
        } catch (Exception e) {
            // 处理其他异常
            throw new BaseException("处理token时发生错误");
        }
    }


}
